//
//  CityDOCatchCrashVC.m
//  TestCrash
//
//  Created by CityDo on 2019/4/22.
//  Copyright © 2019 CityDo. All rights reserved.
//

#import "CityDOCatchCrashVC.h"
#import "CityDOCrashConfig.h"


@interface CityDOCatchCrashVC ()
    @property (copy,nonatomic)    NSMutableDictionary * _Nullable mutableDict;
    @property (copy,nonatomic)    NSDictionary *relatedDataDict;

//@property (copy,nonatomic)    NSMutableDictionary *mutableDict;

    @property (strong, nonatomic) NSString * logInfo;
    @property (strong, nonatomic) NSString * excepUser;
    @property (strong, nonatomic) NSString * channel;
    @property (strong, nonatomic) NSString * all_disk;//磁盘总空间
    @property (strong, nonatomic) NSString * all_memory;//内存总空间
    @property (strong, nonatomic) NSString * relatedDataKey;
    @property (strong, nonatomic) NSString * relatedDataValue;
    @property (strong, nonatomic) NSString * appId;//
    @property (strong, nonatomic) NSString * appSecret;//

    @property (nonatomic) BOOL collectLogInfoEnable;
    @property (nonatomic) BOOL collectCrashInfoEnable;
@property (strong, nonatomic) NSString * crashInfoURL;//可以自由配置URL
@property (strong, nonatomic) NSString * logInfoURL;//可以自由配置URL

@end

@implementation CityDOCatchCrashVC


+ (CityDOCatchCrashVC *)sharedInstance;
{
    static CityDOCatchCrashVC *_sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[CityDOCatchCrashVC alloc] init];
        CityDOCatchCrash *crashInfo = [[CityDOCatchCrash alloc]init];
        [crashInfo redirectNSLogToDocumentFolder];

    });
    
    return _sharedInstance;
}

+ (CityDOCatchCrashVC *)CityDOCatchStartWithAppId:(NSString *)appId;
{
    CityDOCatchCrashVC *cityDoCrashVC = [self sharedInstance];

       cityDoCrashVC.appId = appId;
       cityDoCrashVC.collectLogInfoEnable = NO;
       cityDoCrashVC.collectCrashInfoEnable = YES;
    return    cityDoCrashVC;
}

+ (CityDOCatchCrashVC *)CityDOCatchStartWithAppId:(NSString *)appId config:( CityDOCrashConfig *)config;
{
    CityDOCatchCrashVC *cityDoCrashVC = [self sharedInstance];
   cityDoCrashVC.appId = appId;
   cityDoCrashVC.collectLogInfoEnable = config.collectLogInfoEnable;
    
    if (   cityDoCrashVC.collectLogInfoEnable) {
           cityDoCrashVC.collectLogInfoEnable = config.collectLogInfoEnable;
    } else {
           cityDoCrashVC.collectLogInfoEnable = NO;
    }
    
    if (config.collectCrashInfoEnable) {
           cityDoCrashVC.collectCrashInfoEnable = config.collectCrashInfoEnable;
    } else {
           cityDoCrashVC.collectCrashInfoEnable = YES;
    }
    
    if (config.logInfoURL) {
           cityDoCrashVC.logInfoURL = config.logInfoURL;
    }
    
    if (config.crashInfoURL) {
           cityDoCrashVC.crashInfoURL = config.crashInfoURL;
    }
    
    return cityDoCrashVC;
}


- (NSMutableDictionary *)mutableDict
{
    if (!_mutableDict) {
        _mutableDict = [NSMutableDictionary dictionary];
    }
    return _mutableDict;
}

+ (void)setUserIdentifier:(nonnull NSString *)excepUser;
{
    if (!excepUser) {
        [self sharedInstance].excepUser =  [[UIDevice currentDevice] uuid];
    }else {
         [self sharedInstance].excepUser =  excepUser;
    }
    
}

+ (void)setChannel:(nonnull NSString *)channel;
{
    if (!channel) {
        [self sharedInstance].channel = @"";
    }
    [self sharedInstance].channel = channel;
}

+ (void)relatedDataValue:(nonnull NSString *)value
          relatedDataKey:(nonnull NSString *)key;
{
    if (!key) {
         [self sharedInstance].relatedDataKey = @"";
    } else {
        [self sharedInstance].relatedDataKey = key;
    }
    
    if (!value) {
        [self sharedInstance].relatedDataValue = @"";
    } else {
        [self sharedInstance].relatedDataValue = value;
    }

}


- (NSDictionary *)dataOrStringToDictionary:(id)object {
    
    if ([object isKindOfClass:[NSData class]]) {
        
        return [self dataToDictionary:object];
        
    }else if ([object isKindOfClass:[NSString class]]) {
        
        NSData *data = [object dataUsingEncoding:NSUTF8StringEncoding];
        
        return [self dataToDictionary:data];
        
    }else if ([object isKindOfClass:[NSDictionary class]]) {
        
        return (NSDictionary *)object;
    }
    
    return nil;
}

- (NSDictionary *)dataToDictionary:(NSData *)date {
    
    NSError *error = nil;
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:date
                                                         options:NSJSONReadingMutableContainers
                                                           error:&error];
    return dict;
}

+ (void)postExceptionMessage;
{
    
    NSDictionary * crashAdditionInfo = [CityDOCatchCrashVC getCrashInfo];
    
    [[self sharedInstance] deleteAllFiles];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
//    NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.txt"];
    NSString *allThreadInfologFilePath = [logDirectory stringByAppendingPathComponent:@"allThreads.txt"];
    NSString *mainThreadLogFilePath= [logDirectory stringByAppendingPathComponent:@"mainThread.txt"];
    NSString *currentThreadLogFilePath = [logDirectory stringByAppendingPathComponent:@"currentThread.txt"];
    
    NSArray *filesArray = @[allThreadInfologFilePath, currentThreadLogFilePath,mainThreadLogFilePath];
    
    [HelperUtil uploadFiles:[self sharedInstance].crashInfoURL fieldName:@"userfile" filePaths:filesArray  params:crashAdditionInfo];
    
}

+ (void)postLogInfo;
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
    NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.txt"];
    //NSString类方法读取内容
    NSString *breakLog = [NSString stringWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"NSString类方法读取的内容是：\n%@",breakLog);
    [self sharedInstance].logInfo = breakLog;
    NSData *breakLogData =[breakLog dataUsingEncoding:NSUTF8StringEncoding];
    
    NSString *deviceId  = [[UIDevice currentDevice] uuid];
    NSDictionary *paramsForUPload = @{@"deviceId":deviceId};
    
    if (![self sharedInstance].logInfoURL) {
        [self sharedInstance].logInfoURL = @"";
        NSLog(@" ===============日志收集数据请求的URL为空===============");
    }
    
    if ( [self sharedInstance].collectLogInfoEnable) {
        
        if (!breakLogData) {
            NSString *str =@"zero";
            breakLogData =[str dataUsingEncoding:NSUTF8StringEncoding];
        }
        [CityDOCatchCrashVC postLogInfo:[self sharedInstance].logInfoURL Data:breakLogData Dict:paramsForUPload];
    }
    
}


+ (void)postLogInfo:(NSString *)url Data:(NSData *)data Dict:(NSDictionary *)dict;
{
      [HelperUtil upload:@"file" filename:@"UncaughtException.txt" url: url mimeType:@"text/plain" data:data parmas:dict];
}

- (void)deleteUncaughtExceptionFile {
    NSString *logDirectory =[self getDocumentsPath];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *iOSPath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.txt"];
    //UncaughtExceptionAllStackInfo.log
    BOOL isSuccess = [fileManager removeItemAtPath:iOSPath error:nil];
    if (isSuccess) {
        NSLog(@"delete success");
    }else{
        NSLog(@"delete fail");
    }
}

- (void)deleteAllStackInfoFile {
    NSString *logDirectory =[self getDocumentsPath];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *iOSPath = [logDirectory stringByAppendingPathComponent:@"UncaughtExceptionAllStackInfo.txt"];
    BOOL isSuccess = [fileManager removeItemAtPath:iOSPath error:nil];
    if (isSuccess) {
        NSLog(@"delete success");
    }else{
        NSLog(@"delete fail");
    }
}

- (void)deleteAllFiles;
{
    NSString *extension = @"txt";
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *documentsDirectory =[self getDocumentsPath];

    NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:NULL];
    NSEnumerator *e = [contents objectEnumerator];
    NSString *filename;
    while ((filename = [e nextObject])) {
        
        if ([[filename pathExtension] isEqualToString:extension]) {
            
            [fileManager removeItemAtPath:[documentsDirectory stringByAppendingPathComponent:filename] error:NULL];
        }
    }
}

-(void)deleteFiles {
    [self deleteUncaughtExceptionFile];
    [self deleteAllStackInfoFile];
}

-(NSString *)getDocumentsPath {
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
    
    return logDirectory;
}

+ (NSDictionary *)getCrashInfo;
{
    
//    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
//    NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.txt"];

    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
    NSDictionary *infoDictionary=[[NSBundle mainBundle] infoDictionary];
    //     当前应用名称
    NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    NSLog(@"当前应用名称：%@",appCurName);
    
    NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"];
    NSLog(@"当前应用版本号码：%@",appCurVersionNum);
    
//    //NSString类方法读取内容
//    NSString *breakLog = [NSString stringWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];
//    NSLog(@"NSString类方法读取的内容是：\n%@",breakLog);
//    [self sharedInstance].logInfo = breakLog;
//    NSData *breakLogData =[breakLog dataUsingEncoding:NSUTF8StringEncoding];
//    NSString *stack = [NSString stringWithContentsOfFile:logFilePathOne encoding:NSUTF8StringEncoding error:nil];
    
    NSString *isJailbreak = [NSString stringWithFormat:@"%d", [HelperUtil isJailbreak]];
    if (isJailbreak == nil) {
        isJailbreak = @"";
    }
    
    [formatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
    NSString *startTime = [formatter stringFromDate:[NSDate date]];
    NSString *memory = [HelperUtil getFreeMemoryInfo];
    NSString  *bundleId =[[NSBundle mainBundle] bundleIdentifier];
    NSString *systemVersion  = [[UIDevice currentDevice] systemVersion];
    NSString *deviceModel = [JDDeviceUtils deviceTypeStr];
    NSString *cpuFramework = [HelperUtil getCPUType];
    NSString *deviceId  = [[UIDevice currentDevice] uuid];
    NSString *disk = [HelperUtil freeDiskSpaceInBytes];
    
    if (![self sharedInstance].logInfoURL) {
        [self sharedInstance].logInfoURL = @"";
        NSLog(@" ===============日志收集数据请求的URL为空===============");
    }
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *stackDict =  [defaults valueForKey:@"dict"];
    

    if (stackDict) {
    }
    
    if ( ![self sharedInstance].excepUser) {
        [self sharedInstance].excepUser =  [[UIDevice currentDevice] uuid];
    }
    
    if ( ![self sharedInstance].channel) {
        [self sharedInstance].channel = @"";
    }
    
    if (![self sharedInstance].relatedDataKey) {
        [self sharedInstance].relatedDataKey = @"";
    }
    
    if (![self sharedInstance].relatedDataValue) {
        [self sharedInstance].relatedDataValue = @"";
    }
    
    if (![self sharedInstance].appId) {
        [self sharedInstance].appId = @"";
    }
    
    if (![self sharedInstance].appSecret) {
        [self sharedInstance].appSecret = @"";
    }
    
    //三种获取方式
    NSString * oneUUID = [HelperUtil ExecutableUUID];
    NSUUID  *twoUUID =  ExecutableUUID();
    NSUUID *threeUUID =  [HelperUtil ExecutableUUID];
    //    ,@"twoUUID":twoUUID.UUIDString,@"threeUUID":threeUUID.UUIDString
    NSDictionary *dictUUID=@{@"oneUUID":oneUUID,@"twoUUID":twoUUID.UUIDString,@"threeUUID":threeUUID.UUIDString};
    //    NSString *UUIDStringS = [HelperUtil dataTOjsonString:dictUUID];
    
    NSDictionary *dict=@{@"appName":appCurName,@"stack":oneUUID,@"appVersion":appCurVersionNum,@"isJailbreak":isJailbreak,@"sdkVersion":@"1.0",@"pageTrace":@"开发中",@"startTime":startTime,@"bundleId":bundleId,@"systemVersion":systemVersion,@"deviceModel":deviceModel,@"deviceId":deviceId,@"cpuFramework":cpuFramework,@"channel":@"杭州",@"relatedDataKey": [self sharedInstance].relatedDataKey,@"relatedDataValue":[self sharedInstance].relatedDataValue,@"channel": [self sharedInstance].channel,@"excepUser": [self sharedInstance].excepUser,@"allDisk":[HelperUtil getTotalDiskSpace],@"disk":disk,@"allMemory":[HelperUtil getTotalMemoryInfo],@"memory":memory,@"appId":[self sharedInstance].appId,@"secret":[self sharedInstance].appSecret};
    
    
    [[self sharedInstance].mutableDict addEntriesFromDictionary:stackDict];
    [[self sharedInstance].mutableDict  addEntriesFromDictionary:dict];
    NSDictionary * aa = [self sharedInstance].mutableDict;
//    [[self sharedInstance] postExceptionMessage];
    return [self sharedInstance].mutableDict;
}

+ (NSString *)getLogInfo;
{
    NSArray  *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
    NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.txt"];
//    NSString *logFilePathOne = [logDirectory stringByAppendingPathComponent:@"UncaughtExceptionAllStackInfo.txt"];
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
    //    NSString *dateStr = [formatter stringFromDate:[NSDate date]];
    
    NSDictionary *infoDictionary=[[NSBundle mainBundle] infoDictionary];
    //     当前应用名称
    NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    NSLog(@"当前应用名称：%@",appCurName);
    
    NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"];
    NSLog(@"当前应用版本号码：%@",appCurVersionNum);
    //NSString类方法读取内容
    NSString *breakLog = [NSString stringWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"NSString类方法读取的内容是：\n%@",breakLog);
    
    return breakLog;

}

@end
